'use client';

import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react';
import { io, Socket } from 'socket.io-client';

// 定义消息类型
export interface Message {
  id: string;
  sender: string;
  content: string;
  timestamp: number;
  receiver?: string;
  groupId?: string;
}

// 定义用户类型
export interface User {
  id: string;
  username: string;
  avatar: string;
  online: boolean;
}

// 定义群组类型
export interface Group {
  id: string;
  name: string;
  avatar: string;
  memberCount: number;
  createdBy: string;
}

// 定义好友请求类型
export interface FriendRequest {
  id: string;
  sender: string;
  receiver: string;
  status: 'pending' | 'accepted' | 'rejected';
  timestamp: number;
}

// 定义聊天类型
export type ChatType = 'private' | 'group';

// 定义聊天信息
export interface Chat {
  id: string; // 对于私聊是用户ID，对于群聊是群组ID
  type: ChatType;
  name: string;
  avatar: string;
  lastMessage?: string;
  lastMessageTime?: number;
  unreadCount: number;
}

// 定义Socket上下文类型
interface SocketContextType {
  socket: Socket | null;
  connected: boolean;
  currentUser: User | null;
  friends: User[];
  groups: Group[];
  chats: Chat[];
  currentChat: Chat | null;
  messages: Message[];
  friendRequests: Array<FriendRequest & { sender: User }>;
  groupMembers: User[];
  
  // 方法
  login: (userId: string) => void;
  sendPrivateMessage: (receiverId: string, content: string) => void;
  sendGroupMessage: (groupId: string, content: string) => void;
  loadPrivateChatHistory: (friendId: string) => void;
  loadGroupChatHistory: (groupId: string) => void;
  sendFriendRequest: (targetUserId: string) => void;
  handleFriendRequest: (requestId: string, accept: boolean) => void;
  createGroup: (groupName: string, members: string[]) => void;
  getGroupMembers: (groupId: string) => void;
  setCurrentChat: (chat: Chat | null) => void;
}

// 创建上下文
const SocketContext = createContext<SocketContextType | undefined>(undefined);

// 上下文提供者组件
export const SocketProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const [socket, setSocket] = useState<Socket | null>(null);
  const [connected, setConnected] = useState(false);
  const [currentUser, setCurrentUser] = useState<User | null>(null);
  const [friends, setFriends] = useState<User[]>([]);
  const [groups, setGroups] = useState<Group[]>([]);
  const [chats, setChats] = useState<Chat[]>([]);
  const [currentChat, setCurrentChat] = useState<Chat | null>(null);
  const [messages, setMessages] = useState<Message[]>([]);
  const [friendRequests, setFriendRequests] = useState<Array<FriendRequest & { sender: User }>>([]);
  const [groupMembers, setGroupMembers] = useState<User[]>([]);

  // 初始化Socket连接
  useEffect(() => {
    // 在客户端环境中创建Socket连接
    if (typeof window !== 'undefined') {
      const socketInstance = io('http://localhost:3000', {
        path: '/socket.io',
        autoConnect: false
      });

      setSocket(socketInstance);

      // 连接事件处理
      socketInstance.on('connect', () => {
        console.log('Socket连接成功');
        setConnected(true);
      });

      socketInstance.on('disconnect', () => {
        console.log('Socket连接断开');
        setConnected(false);
      });

      // 登录成功事件
      socketInstance.on('login_success', ({ user }) => {
        setCurrentUser(user);
      });

      // 登录错误事件
      socketInstance.on('login_error', ({ message }) => {
        console.error('登录错误:', message);
      });

      // 好友列表事件
      socketInstance.on('friends_list', ({ friends: friendsList }) => {
        setFriends(friendsList);
        
        // 更新聊天列表
        const friendChats = friendsList.map((friend: { id: any; username: any; avatar: any; }) => ({
          id: friend.id,
          type: 'private' as ChatType,
          name: friend.username,
          avatar: friend.avatar,
          unreadCount: 0
        }));
        
        setChats(prevChats => {
          const groupChats = prevChats.filter(chat => chat.type === 'group');
          return [...friendChats, ...groupChats];
        });
      });

      // 群组列表事件
      socketInstance.on('groups_list', ({ groups: groupsList }) => {
        setGroups(groupsList);
        
        // 更新聊天列表
        const groupChats = groupsList.map((group: { id: any; name: any; avatar: any; }) => ({
          id: group.id,
          type: 'group' as ChatType,
          name: group.name,
          avatar: group.avatar,
          unreadCount: 0
        }));
        
        setChats(prevChats => {
          const privateChats = prevChats.filter(chat => chat.type === 'private');
          return [...privateChats, ...groupChats];
        });
      });

      // 新私聊消息事件
      socketInstance.on('new_private_message', (message) => {
        // 如果当前正在查看该聊天，则添加消息到消息列表
        if (currentChat && currentChat.type === 'private' && 
            (currentChat.id === message.sender || currentChat.id === message.receiver)) {
          setMessages(prevMessages => [...prevMessages, message]);
        } else {
          // 否则增加未读消息计数
          setChats(prevChats => {
            return prevChats.map(chat => {
              if (chat.type === 'private' && chat.id === message.sender) {
                return {
                  ...chat,
                  lastMessage: message.content,
                  lastMessageTime: message.timestamp,
                  unreadCount: chat.unreadCount + 1
                };
              }
              return chat;
            });
          });
        }
      });

      // 新群聊消息事件
      socketInstance.on('new_group_message', (message) => {
        // 如果当前正在查看该群聊，则添加消息到消息列表
        if (currentChat && currentChat.type === 'group' && currentChat.id === message.groupId) {
          setMessages(prevMessages => [...prevMessages, message]);
        } else {
          // 否则增加未读消息计数
          setChats(prevChats => {
            return prevChats.map(chat => {
              if (chat.type === 'group' && chat.id === message.groupId) {
                return {
                  ...chat,
                  lastMessage: message.content,
                  lastMessageTime: message.timestamp,
                  unreadCount: chat.unreadCount + 1
                };
              }
              return chat;
            });
          });
        }
      });

      // 私聊历史消息事件
      socketInstance.on('private_chat_history', ({ friendId, messages: historyMessages }) => {
        setMessages(historyMessages);
        
        // 重置未读消息计数
        setChats(prevChats => {
          return prevChats.map(chat => {
            if (chat.type === 'private' && chat.id === friendId) {
              return {
                ...chat,
                unreadCount: 0
              };
            }
            return chat;
          });
        });
      });

      // 群聊历史消息事件
      socketInstance.on('group_chat_history', ({ groupId, messages: historyMessages }) => {
        setMessages(historyMessages);
        
        // 重置未读消息计数
        setChats(prevChats => {
          return prevChats.map(chat => {
            if (chat.type === 'group' && chat.id === groupId) {
              return {
                ...chat,
                unreadCount: 0
              };
            }
            return chat;
          });
        });
      });

      // 好友状态变化事件
      socketInstance.on('friend_status_change', ({ userId, online }) => {
        setFriends(prevFriends => {
          return prevFriends.map(friend => {
            if (friend.id === userId) {
              return { ...friend, online };
            }
            return friend;
          });
        });
      });

      // 新好友请求事件
      socketInstance.on('new_friend_request', ({ request, sender }) => {
        setFriendRequests(prevRequests => [
          ...prevRequests,
          { ...request, sender }
        ]);
      });

      // 好友请求已接受事件
      socketInstance.on('friend_request_accepted', ({ requestId, friend }) => {
        // 添加新好友到好友列表
        setFriends(prevFriends => [...prevFriends, friend]);
        
        // 添加新聊天到聊天列表
        setChats(prevChats => [
          ...prevChats,
          {
            id: friend.id,
            type: 'private',
            name: friend.username,
            avatar: friend.avatar,
            unreadCount: 0
          }
        ]);
      });

      // 好友已添加事件
      socketInstance.on('friend_added', ({ friend }) => {
        // 添加新好友到好友列表
        setFriends(prevFriends => [...prevFriends, friend]);
        
        // 添加新聊天到聊天列表
        setChats(prevChats => [
          ...prevChats,
          {
            id: friend.id,
            type: 'private',
            name: friend.username,
            avatar: friend.avatar,
            unreadCount: 0
          }
        ]);
      });

      // 群组创建事件
      socketInstance.on('group_created', ({ group }) => {
        // 添加新群组到群组列表
        setGroups(prevGroups => [...prevGroups, group]);
        
        // 添加新聊天到聊天列表
        setChats(prevChats => [
          ...prevChats,
          {
            id: group.id,
            type: 'group',
            name: group.name,
            avatar: group.avatar,
            unreadCount: 0
          }
        ]);
      });

      // 群组成员事件
      socketInstance.on('group_members', ({ groupId, members }) => {
        setGroupMembers(members);
      });

      return () => {
        socketInstance.disconnect();
        socketInstance.removeAllListeners();
      };
    }
  }, [currentChat]);

  // 登录方法
  const login = (userId: string) => {
    if (socket && !currentUser) {
      socket.connect();
      socket.emit('login', { userId });
    }
  };

  // 发送私聊消息
  const sendPrivateMessage = (receiverId: string, content: string) => {
    if (socket && currentUser) {
      socket.emit('send_private_message', { receiverId, content });
      
      // 添加消息到本地消息列表（乐观更新）
      const newMessage = {
        id: Date.now().toString(),
        sender: currentUser.id,
        receiver: receiverId,
        content,
        timestamp: Date.now()
      };
      
      setMessages(prevMessages => [...prevMessages, newMessage]);
    }
  };

  // 发送群聊消息
  const sendGroupMessage = (groupId: string, content: string) => {
    if (socket && currentUser) {
      socket.emit('send_group_message', { groupId, content });
      
      // 添加消息到本地消息列表（乐观更新）
      const newMessage = {
        id: Date.now().toString(),
        sender: currentUser.id,
        groupId,
        content,
        timestamp: Date.now()
      };
      
      setMessages(prevMessages => [...prevMessages, newMessage]);
    }
  };

  // 加载私聊历史消息
  const loadPrivateChatHistory = (friendId: string) => {
    if (socket && currentUser) {
      socket.emit('get_private_chat_history', { userId: currentUser.id, friendId });
    }
  };

  // 加载群聊历史消息
  const loadGroupChatHistory = (groupId: string) => {
    if (socket && currentUser) {
      socket.emit('get_group_chat_history', { groupId });
    }
  };

  // 发送好友请求
  const sendFriendRequest = (targetUserId: string) => {
    if (socket && currentUser) {
      socket.emit('send_friend_request', { targetUserId });
    }
  };

  // 处理好友请求
  const handleFriendRequest = (requestId: string, accept: boolean) => {
    if (socket && currentUser) {
      socket.emit('handle_friend_request', { requestId, accept });
      
      // 从请求列表中移除
      setFriendRequests(prevRequests => 
        prevRequests.filter(request => request.id !== requestId)
      );
    }
  };

  // 创建群组
  const createGroup = (groupName: string, members: string[]) => {
    if (socket && currentUser) {
      socket.emit('create_group', { groupName, members });
    }
  };

  // 获取群组成员
  const getGroupMembers = (groupId: string) => {
    if (socket && currentUser) {
      socket.emit('get_group_members', { groupId });
    }
  };

  // 提供上下文值
  const contextValue: SocketContextType = {
    socket,
    connected,
    currentUser,
    friends,
    groups,
    chats,
    currentChat,
    messages,
    friendRequests,
    groupMembers,
    login,
    sendPrivateMessage,
    sendGroupMessage,
    loadPrivateChatHistory,
    loadGroupChatHistory,
    sendFriendRequest,
    handleFriendRequest,
    createGroup,
    getGroupMembers,
    setCurrentChat
  };

  return (
    <SocketContext.Provider value={contextValue}>
      {children}
    </SocketContext.Provider>
  );
};

// 自定义Hook，用于在组件中访问上下文
export const useSocket = () => {
  const context = useContext(SocketContext);
  if (context === undefined) {
    throw new Error('useSocket must be used within a SocketProvider');
  }
  return context;
};